/*
 * TimePoint.java
 * 
 * Copyright 2008 David D. Emory
 * 
 * This file is part of Five Points. See <http://www.fpdev.org> for
 * additional information regarding the project.
 * 
 * Five Points is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Five Points is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with Five Points.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.fpdev.core.transit;

import org.fpdev.core.basenet.BLink;
import org.fpdev.core.basenet.BNode;
import org.fpdev.util.FPUtil;

import java.awt.*;
import org.fpdev.core.basenet.BaseNetwork;
import org.fpdev.apps.rtemaster.gui.map.MapCanvas;

public class TimePoint extends Stop {

  private int index_;

  // id-based constructors
  
  public TimePoint(TransitPath tpath, int nodeID, int index, int inPLI, int outPLI) {
    this(tpath, nodeID, index, "", inPLI, outPLI);
  }

  public TimePoint(TransitPath tpath, int nodeID, int index, String name, int inPLI, int outPLI) {
    super(tpath, nodeID, name, inPLI, outPLI);
    index_ = index;
  }

  // node-based constructors

  public TimePoint(TransitPath tpath, BNode node, int index, int inPLI, int outPLI) {
    this(tpath, node, index, "", inPLI, outPLI);
  }

  public TimePoint(TransitPath tpath, BNode node, int index, String name, int inPLI, int outPLI) {
    super(tpath, node, name, inPLI, outPLI);
    index_ = index;
  }

  public int getIndex() {
    return index_;
  }

  public void setIndex(int i) {
    index_ = i;
  }

  @Override
  public int getType() {
    return STOP_TIMEPOINT;
  }

  @Override
  public void setNode(BNode node) {
    //System.out.println("tpt "+index_+" set node="+node.getID());
    node_ = node;
  }

  @Override
  public void draw(MapCanvas canvas, int width, boolean annotate) {
    //System.out.println("drawing tpti "+index_);
    BaseNetwork baseNet = canvas.getBaseNet();
    double nx = node_.getX(), ny = node_.getY();

    double ix = 0, iy = 0, ivxn = 0, ivyn = 0;
    if (inPLI_ != -1) { // not first tPt
      BLink inLink = tpath_.getLink(inPLI_);
      //Vertex inOppV = .opposite(node_.getVertex(), inLink.getEdge());
      BNode inOppNode = baseNet.opposite(node_, inLink);
      ix = inOppNode.getX();
      iy = inOppNode.getY();
      double ivx = ix - nx;
      double ivy = iy - ny;
      double ivm = FPUtil.magnitude(nx, ny, ix, iy);
      ivxn = ivx * (1.0 / ivm);
      ivyn = ivy * (1.0 / ivm);
    }

    double ox = 0, oy = 0, ovxn = 0, ovyn = 0;
    if (outPLI_ != -1) { // not last tPt
      BLink outLink = tpath_.getLink(outPLI_);
      //System.out.println("tpt "+index_+" opp: "+node_.getID()+" "+outLink.getID());
      BNode outOppNode = baseNet.opposite(node_, outLink);
      ox = outOppNode.getX();
      oy = outOppNode.getY();
      double ovx = ox - nx;
      double ovy = oy - ny;
      double ovm = FPUtil.magnitude(nx, ny, ox, oy);
      ovxn = ovx * (1.0 / ovm);
      ovyn = ovy * (1.0 / ovm);
    }

    double mvxn, mvyn;

    if (ix == 0) {
      //System.out.println(" ix=0");
      double angle = -Math.PI / 2;
      double ca = Math.cos(angle);
      double sa = Math.sin(angle);
      mvxn = ovxn * ca - ovyn * sa;
      mvyn = ovxn * sa + ovyn * ca;
    } else if (ox == 0) {
      //System.out.println(" ox=0");
      double angle = Math.PI / 2;
      double ca = Math.cos(angle);
      double sa = Math.sin(angle);
      mvxn = ivxn * ca - ivyn * sa;
      mvyn = ivxn * sa + ivyn * ca;
    } else {
      double mx = ((nx + ivxn) + (nx + ovxn)) / 2.0;
      double my = ((ny + ivyn) + (ny + ovyn)) / 2.0;

      double mvx = mx - nx, mvy = my - ny;
      double mvm = FPUtil.magnitude(nx, ny, mx, my);
      //System.out.println(" mvm="+mvm);
      if (mvm < .00001) {
        double angle = -Math.PI / 2;
        double ca = Math.cos(angle);
        double sa = Math.sin(angle);
        mvxn = ovxn * ca - ovyn * sa;
        mvyn = ovxn * sa + ovyn * ca;
      } else {

        // normalize vectors
        mvxn = mvx * (1.0 / mvm);
        mvyn = mvy * (1.0 / mvm);

        if (java.awt.geom.Line2D.relativeCCW(ix, iy, nx, ny, ox, oy) == -1) {
          mvxn = -mvxn;
          mvyn = -mvyn;
        }
      }
    }

    double cx = nx + canvas.getCC().dxToWorld(10) * mvxn;
    double cy = ny + canvas.getCC().dyToWorld(10) * mvyn;

    //canvas.getGraphics().setColor(Color.blue);
    canvas.getGraphics().setStroke(new BasicStroke(width, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
    canvas.drawLine(nx, ny, cx, cy);

    canvas.drawPoint(cx, cy, width + 6);
    if (annotate) {
      canvas.getGraphics().setColor(Color.black);
      canvas.drawText("" + index_, 7, cx, cy, -2, 3);
    }
  }

  public Stop createCopy(TransitPath newPath) {
    if(node_ != null) return new TimePoint(newPath, node_, index_, inPLI_, outPLI_);
    return new TimePoint(newPath, nodeID_, index_, inPLI_, outPLI_);
  }
}

















